package main

import (
	"fmt"
	"sync"
)

type safeMapx[Key comparable, Value any] struct {
	mux sync.RWMutex
	m   map[Key]Value
}

func (m *safeMapx[Key, Value]) GetKey(k Key) (Value, bool) {
	//TODO implement me
	panic("implement me")
}

func (m *safeMapx[Key, Value]) Set(k Key, value Value) {
	m.mux.Lock()
	defer m.mux.Unlock()
	m.m[k] = value
}

func (m *safeMapx[Key, Value]) Delete(k Key) {
	m.mux.Lock()
	defer m.mux.Unlock()
	delete(m.m, k)
}

func (m *safeMapx[Key, Value]) Range(fn func(Key, Value)) {
	m.mux.RLock()
	data := m.m
	m.mux.RUnlock()
	for k, v := range data {
		fn(k, v)
	}
}

func (m *safeMapx[Key, Value]) Keys() []Key {
	m.mux.RLock()
	defer m.mux.RUnlock()
	keys := make([]Key, 0, len(m.m))
	for k, v := range m.m {
		keys = append(keys, k)
		fmt.Println(k, v)
	}
	return keys
}

func newSafeMapx[Key comparable, Value any]() *safeMapx[Key, Value] {
	return &safeMapx[Key, Value]{m: make(map[Key]Value)}
}

func (m *safeMapx[Key, Value]) Get(key Key) (Value, bool) {
	m.mux.RLock()
	defer m.mux.RUnlock()
	val, ok := m.m[key]
	return val, ok
}
func (m *safeMapx[Key, Value]) Len() int {
	m.mux.RLock()
	defer m.mux.RUnlock()
	return len(m.m)
}
